
package dieci.database.client;

import dieci.database.PersistentObject;
import dieci.database.SessionFactoryUtil;
import dieci.hibernate.HibClient;
import dieci.system.Client;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

/**
 *
 * @author DuckSys
 */
public class ClientHibernateDAO implements ClientDAO
{
    private static Logger logger = Logger.getLogger("ClientHibernateDAO.log");

    @Override
    public List<Client> list()
    {
        List<Client> clients = new ArrayList<>();

        Session session = SessionFactoryUtil.getInstance().getCurrentSession();
        try {
            session.beginTransaction();

            List<HibClient> hibClients = session.createCriteria(HibClient.class).
                    add(Restrictions.eq("deleted", 0)).addOrder(Order.asc("name")).list();
            for (HibClient dbClient : hibClients) {
                Client cli = new Client(dbClient.getClientId(),dbClient.getName(),dbClient.getPhoneNumber(),dbClient.getEmail(),
                        dbClient.getAddress(),dbClient.getContactPerson(),
                        dbClient.getWebSite(),dbClient.getDeleted());
                clients.add(cli);
            }

            return clients;
        }
        catch (Exception e) {

            logger.log(Level.INFO, "Error listando clientes", e.getMessage());

            throw new IllegalStateException("Error al listar",e);
        }
        finally {
            if (session!=null && session.isOpen()) {

                session.close();
            }
        }

    }

    @Override
    public Client findByClientName(String name)
    {
        Client result = null;
        Session session = SessionFactoryUtil.getInstance().getCurrentSession();
        try {
            session.beginTransaction();

            HibClient hibClient = (HibClient) session.createCriteria(HibClient.class).
                    add(Restrictions.eq("deleted", 0)).add(Restrictions.like("name", name)).uniqueResult();
            if (hibClient != null) {
                result = new Client(hibClient.getName(), hibClient.getEmail(), hibClient.getPhoneNumber(),
                        hibClient.getAddress(),hibClient.getContactPerson(),
                        hibClient.getWebSite(), hibClient.getDeleted());
                result.setClientId(hibClient.getClientId());
            }

        }
        catch (Exception e) {
            throw new IllegalStateException("Error al buscar por nombre",e);
        }
        finally {
            if (session!=null && session.isOpen()) {

                session.close();
            }
        }

        return result;

    }

    @Override
    public void saveOrUpdate(PersistentObject object)
    {
        Session session = null;

        Client cli = (Client) object;
        Client found = findByClientName(cli.getName());
        try {
            session = SessionFactoryUtil.getInstance().getCurrentSession();
            
            session.beginTransaction();

            if (found != null) 
            {
                //UPDATE
                cli.setClientId(found.getClientId());
               
                HibClient hibClient = new HibClient(cli.getClientId(), (Client) cli);
                session.saveOrUpdate(hibClient);

            }
            else 
            {
                //NEW
                HibClient hibClient = new HibClient(cli);

                // generate new id for the product
                session.save(hibClient);
                
            }

            session.getTransaction().commit();

        }
        catch (Exception e) {
            if(session!=null){
                session.getTransaction().rollback();
            } 
            throw new IllegalStateException("Error al guardar o actualizar",e);
        }
        finally {
            if (session!=null && session.isOpen()) {

                session.close();
            }
        }
    
    }

    @Override
    public void delete(PersistentObject object)
    {
        Session session = null;

        Client cli = (Client) object;
        Client found = findByClientName(cli.getName());
        try {
            session = SessionFactoryUtil.getInstance().getCurrentSession();
            
            session.beginTransaction();

            if (found != null) 
            {
                //UPDATE
                cli.setClientId(found.getClientId());
               
                HibClient hibClient = new HibClient(cli.getClientId(), (Client) cli);
                hibClient.setDeleted(1);
                session.saveOrUpdate(hibClient);

            }
            
            session.getTransaction().commit();

        }
        catch (Exception e) {
            if(session!=null){
                session.getTransaction().rollback();
            }            
            throw new IllegalStateException("Error al eliminar",e);
        }
        finally {
            if (session!=null && session.isOpen()) {

                session.close();
            }
        }
    }

    @Override
    public Client findById(int id)
    {
        Client result = null;
        Session session = SessionFactoryUtil.getInstance().getCurrentSession();
        try {
            session.beginTransaction();

            HibClient hibClient = (HibClient) session.createCriteria(HibClient.class).
                    add(Restrictions.eq("deleted", 0)).add(Restrictions.eq("clientId", id)).uniqueResult();
            if (hibClient != null) {
                result = new Client(hibClient.getName(), hibClient.getEmail(), hibClient.getPhoneNumber(),
                        hibClient.getAddress(),hibClient.getContactPerson(),
                        hibClient.getWebSite(), hibClient.getDeleted());
                result.setClientId(hibClient.getClientId());
            }

        }
        catch (Exception e) {
            throw new IllegalStateException("Error al buscar por nombre",e);
        }
        finally {
            if (session!=null && session.isOpen()) {

                session.close();
            }
        }

        return result;
    }

}
